/*
 **************************************************************************
 *                                                                        *
 *                     Binary Data Serializer Library                     *
 * Unit Tests                                                             *
 * Author: Arash Partow - 2001                                            *
 * URL: http://www.partow.net                                             *
 *                                                                        *
 * Copyright notice:                                                      *
 * Free use of the Binary Data Serializer Library is permitted under the  *
 * guidelines and in accordance with the most current version of the      *
 * Common Public License.                                                 *
 * http://www.opensource.org/licenses/cpl.php                             *
 *                                                                        *
 **************************************************************************
*/

#include <iostream>
#include <fstream>
#include <string>

#include "serializer.hpp"


struct person
{
public:
   std::string name;
   unsigned int age;
   double height;
   float  weight;

   person()
   {
      name = "";
      age = 0;
      height = 0.0;
      weight = 0.0f;
   }

   bool operator==(const person& p)
   {
      return (p.name   ==   name) &&
             (p.age    ==    age) &&
             (p.weight == weight) &&
             (p.height == height);
   }

   bool operator!=(const person& p)
   {
      return !operator==(p);
   }

   void read(serializer& s)
   {
      s >> name;
      s >> age;
      s >> height;
      s >> weight;
   }

   void write(serializer& s)
   {
      s << name;
      s << age;
      s << height;
      s << weight;
   }
};


bool test01(char* buffer, const unsigned int buffer_size)
{
   serializer s(buffer,buffer_size);
   s.clear();

   person p1;
   person p2;

   p1.name = "abc def ghi jkl";
   p1.age = 123;
   p1.height = 123.4567;
   p1.weight = 765.345f;

   p1.write(s);

   s.reset();

   p2.read(s);

   if (p1 != p2)
   {
      std::cout << "test1 failed!" << std::endl;
      return false;
   }
   return true;
}

bool test02(char* buffer, const unsigned int buffer_size)
{
   serializer s(buffer,buffer_size);
   s.clear();

   person p1;

   p1.name = "abc def ghi jkl";
   p1.age = 0;
   p1.height = 123.4567;
   p1.weight = 765.345f;

   for(int i = 0; i < 10000; ++i, p1.age++, p1.height += 1.23, p1.weight += 4.567f)
   {
      p1.write(s);
   }

   s.reset();

   p1.name = "abc def ghi jkl";
   p1.age = 0;
   p1.height = 123.4567;
   p1.weight = 765.345f;

   person p2;

   for(int i = 0; i < 10000; ++i, p1.age++, p1.height += 1.23, p1.weight += 4.567f)
   {
      p2.read(s);
      if (p1 != p2)
      {
         std::cout << "test2 failed!" << std::endl;
         return false;
      }
   }
   return true;
}

bool test03(char* buffer, const unsigned int buffer_size)
{
   serializer s(buffer,buffer_size);
   s.clear();

   person p1;

   p1.name = "abc def ghi jkl";
   p1.age = 0;
   p1.height = 123.4567;
   p1.weight = 765.345f;

   for(int i = 0; i < 10000; ++i, p1.age++, p1.height += 1.23, p1.weight += 4.567f)
   {
      p1.write(s);
   }

   std::ofstream o_stream("data.txt",std::ios::binary);
   if (!o_stream)
   {
      std::cout << "test3() ERROR - Could not open file!(1)" << std::endl;
      return false;
   }
   s.write_to_stream(o_stream);
   o_stream.close();

   unsigned int length = s.length();

   std::ifstream i_stream("data.txt",std::ios::binary);
   if(!i_stream)
   {
      std::cout << "test3() ERROR - Could not open file!(2)" << std::endl;
      return false;
   }
   s.read_from_stream(i_stream,length);
   s.reset();


   p1.name = "abc def ghi jkl";
   p1.age = 0;
   p1.height = 123.4567;
   p1.weight = 765.345f;

   person p2;

   for(int i = 0; i < 10000; ++i, p1.age++, p1.height += 1.23, p1.weight += 4.567f)
   {
      p2.read(s);
      if (p1 != p2)
      {
         std::cout << "test3 failed!" << std::endl;
         return false;
      }
   }
   return true;
}

int main(void)
{

   const unsigned int max_buffer_size = 65536 * 10;
   char* buffer = new char[max_buffer_size];

   test01(buffer,max_buffer_size);
   test02(buffer,max_buffer_size);
   test03(buffer,max_buffer_size);

   delete[] buffer;

   return 0;
}
